//
//  QHReader.m
//  QHAudioConverterMan
//
//  Created by Anakin chen on 2021/4/12.
//

#import "QHReader.h"

#import "QHUtil.h"
#import "QHConfig.h"

/*
 [AAC ADTS格式分析_T的专栏-CSDN博客](https://blog.csdn.net/tantion/article/details/82743942)
 
 这里只解析 ADTS 的 aac，读取每块header + body，header 只读取 size，其他信息则写固定。
 */

@interface QHReader ()

@property (nonatomic) FILE *in_file;

@end

@implementation QHReader

- (instancetype)init {
    self = [super init];
    if (self) {
        [self p_setup];
    }
    return self;
}

#pragma mark - Public

- (BOOL)aac_is_eof {
    return feof(_in_file);
}

- (void)read_config_from_aac_raw_buf:(void(^)(float sampleRate, int channels))complete {
    FILE *file = [QHUtil copy2Caches:[QHConfig sharestance].acc_name ofType:@"aac"];
    
    int head_buf_size = 7;
    int *head_buf = malloc(head_buf_size);
    fread(head_buf, 1, head_buf_size, file);
    
    int freqIdx = ((int)(*(((uint8_t *)head_buf) + 2))&0x3C) >> 2;
    int c1 = ((int)(*(((uint8_t *)head_buf) + 2))&0x1) << 2;
    int c2 = ((int)(*(((uint8_t *)head_buf) + 3))&0xC0) >> 6;
    int chanCfg = c1 + c2;
    
    complete(freqIdx == 3 ? 48000 : 44100, chanCfg);
    fclose(file);
}

- (NSData *)read_aac_raw_buf {
    if ([self aac_is_eof]) {
        return nil;
    }
    
    int head_buf_size = 7;
    int *head_buf = malloc(head_buf_size);
    fread(head_buf, 1, head_buf_size, _in_file);
    
    int s1 = ((int)(*(((uint8_t *)head_buf) + 3))&0x3) << 11;
    int s2 = ((int)(*(((uint8_t *)head_buf) + 4))) << 3;
    int s3 = (int)(*(((uint8_t *)head_buf) + 5)) >> 5;
    int size = s1 + s2 + s3;
    
    int raw_buf_size = size - head_buf_size;
    int *raw_buf = malloc(raw_buf_size);
    fread(raw_buf, 1, raw_buf_size, _in_file);
    
    return [[NSData alloc] initWithBytes:raw_buf length:raw_buf_size];
}

- (void)close {
    fclose(_in_file);
}

#pragma mark - Pirvate

- (void)p_setup {
    _in_file = [QHUtil copy2Caches:[QHConfig sharestance].acc_name ofType:@"aac"];
}

@end
